package com.jaredrummler.ohos.colorpicker.utils;

import ohos.agp.colors.RgbColor;

public class ColorUtils {
    public static float calculateLuminance(int color) {
        RgbColor rc = RgbColor.fromArgbInt(color);
        // calc it by self, hsvColor will get the wrong result (0.299*R + 0.587*G + 0.114*B)
        return (float) (0.2126 * rc.getRed() + 0.7152 * rc.getGreen() + 0.0722 * rc.getBlue()) / 255f;
    }

    public static int ConvertHSVtoRGB(int alpha, float h, float s, float v) {
        int color = ConvertHSVtoRGB(h, s, v);
        RgbColor c = RgbColor.fromArgbInt(color);
        c.setAlpha(alpha);

        return c.asArgbInt();
    }

    public static int ConvertHSVtoRGB(float h, float s, float v) {
        int i;
        float low, mid1, mid2;
        float r1 = 0, g1 = 0, b1 = 0;
        int r, g, b;

        while (h < 0) {
            h = h + 360;
        }
        while (h >= 360) {
            h = h - 360;
        }

        float hh = ((h / 360) * 6);
        //System.out.println(hh);
        if (s == 0) {
            r = (int) (v * 255);
            g = (int) (v * 255);
            b = (int) (v * 255);
        } else {
            if (hh == 6) {
                hh = 0;
            }

            i = (int) Math.floor(hh);
            // System.out.println(i);
            low = v * (1 - s);
            mid1 = v * (1 - s * (hh - i));
            mid2 = v * (1 - s * (1 - (hh - i)));


            switch (i) {
                case 0:
                    r1 = v;
                    g1 = mid2;
                    b1 = low;
                    break;
                case 1:
                    r1 = mid1;
                    g1 = v;
                    b1 = low;
                    break;
                case 2:
                    r1 = low;
                    g1 = v;
                    b1 = mid2;
                    break;
                case 3:
                    r1 = low;
                    g1 = mid1;
                    b1 = v;
                    break;
                case 4:
                    r1 = mid2;
                    g1 = low;
                    b1 = v;
                    break;
                case 5:
                    r1 = v;
                    g1 = low;
                    b1 = mid1;
                    break;
            }

            r = (int) (r1 * 255);
            g = (int) (g1 * 255);
            b = (int) (b1 * 255);
        }
        return new RgbColor(r, g, b).asArgbInt();

    }

    public static double[] rgbToHsv(double r, double g, double b) {

        // R, G, B values are divided by 255
        // to change the range from 0..255 to 0..1
        r = r / 255.0d;
        g = g / 255.0d;
        b = b / 255.0d;

        // h, s, v = hue, saturation, value
        double cmax = Math.max(r, Math.max(g, b)); // maximum of r, g, b
        double cmin = Math.min(r, Math.min(g, b)); // minimum of r, g, b
        double diff = cmax - cmin; // diff of cmax and cmin.
        double h = -1, s = -1;

        // if cmax and cmax are equal then h = 0
        if (cmax == cmin)
            h = 0;

            // if cmax equal r then compute h
        else if (cmax == r)
            h = (60 * ((g - b) / diff) + 360) % 360;

            // if cmax equal g then compute h
        else if (cmax == g)
            h = (60 * ((b - r) / diff) + 120) % 360;

            // if cmax equal b then compute h
        else if (cmax == b)
            h = (60 * ((r - g) / diff) + 240) % 360;

        // if cmax equal zero
        if (cmax == 0)
            s = 0;
        else
            s = (diff / cmax) * 100;

        // compute v
        double v = cmax * 100;
        return new double[]{h, s / 100f, v / 100f};

    }
}
